package org.turbobytes.unikey.generator;

import org.turbobytes.unikey.IdGenerator;
import org.turbobytes.unikey.util.FileUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.lang.reflect.ParameterizedType;
import java.util.Properties;

/**
 * All Id Generators perform a similar task of generating unique identifiers. This being the case, it is
 * conceivable that all of them will have one or more common tasks to perform.
 * All Id Generators also have to conform to IdGenerator<T> interface.
 * To accomodate common tasks and also achieve the common task of making all Id generators implement
 * IdGenerator<T>, BaseIdGenerator was created. So, unless an implementation wants to extend some other class
 * and doesn't have an option to extend BaseIdGenerator<T>, it is recommended to extend this class.
 * But, as always, since an IdGenerator just have to conform to an interface it is not mandatory. 
 *
 * @author Ganeshji Marwaha
 * @since Aug 5, 2010
 */
public abstract class BaseIdGenerator<T> implements IdGenerator<T> {

  protected final Log log = LogFactory.getLog(getClass());
  
  // Default properties file names for default properties and user supplied properties
  protected String defaultConfigFileName;
  protected String userConfigFileName;

  protected Class<T> idClass;

  /**
   * Extracts the type arguments and stores it in a class level variable.
   * TODO: Now, the extracted type argument is not used. If it is not used for long, it can be deleted
   */
  public BaseIdGenerator() {
    idClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
  }

  /**
   * Merges the defaultConfiguration for this IdGenerator with the user supplied configuration
   *
   * @param userConfiguration - This is the user given configuration to override the default configuration
   * @return the merged configuration properties
   */
  protected Properties getMergedConfig(Properties userConfiguration) {
    // This is the default mergedConfiguration that is available within unikey jar
    Properties defaultConfiguration = FileUtil.loadPropertiesFromClasspath(defaultConfigFileName);

    // Override defaultConfiguration with userConfiguration. Will never return null
    return FileUtil.mergeProperties(defaultConfiguration, userConfiguration);
  }

}
